/*
 * @(#)RequestModelInjectInterceptor.java $version 2010. 8. 11
 *
 * Copyright 2007-2010 NHN Corp. All rights Reserved. 
 * NHN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */
package com.nhncorp.usf.core.interceptor.impl;

import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.nhncorp.lucy.web.helper.ServletHelper;
import com.nhncorp.lucy.web.interceptor.AbstractInterceptor;
import com.nhncorp.usf.core.result.helper.FreemarkerConfigFactory;
import com.nhncorp.usf.core.xwork.ActionInvocationHelper;

import com.opensymphony.xwork.ActionInvocation;
import com.opensymphony.xwork.interceptor.PreResultListener;

import freemarker.ext.beans.BeansWrapper;
import freemarker.template.Configuration;
import freemarker.template.ObjectWrapper;
import freemarker.template.TemplateModelException;

/**
 * DataMap에 있는 결과데이터를 Request에 담음.
 *
 * @author Web Platform Development Team
 */
@SuppressWarnings("serial")
public class RequestModelInjectInterceptor extends AbstractInterceptor {

    Log log = LogFactory.getLog(RequestModelInjectInterceptor.class);

    /**
     * @param actionInvocation the ActionInvocation
     * @return the interceptor result
     * @throws Exception for Exception
     */
    @Override
    public String intercept(ActionInvocation actionInvocation) throws Exception {
        actionInvocation.addPreResultListener(new PreResultListener() {

            public void beforeResult(ActionInvocation actionInvocation, String resultCode) {
                // inject result
                HttpServletRequest request = ServletHelper.getRequest(actionInvocation);
                Map<String, Object> dataMap = ActionInvocationHelper.getDataMap(actionInvocation);
                log.debug("copy result data : " + dataMap.size());

                for (Entry<String, Object> entry : dataMap.entrySet()) {
                    request.setAttribute(entry.getKey(), entry.getValue());
                }

                // inject sharedVariable
                Configuration config = FreemarkerConfigFactory.getConfiguration();
                ObjectWrapper wrapper = config.getObjectWrapper();

                if (!(wrapper instanceof BeansWrapper)) {
                    log.warn("the wrapper is not BeansWrapper");
                    return;
                }

                BeansWrapper beanWrapper = (BeansWrapper)wrapper;

                for (Object varName : config.getSharedVariableNames()) {
                    if (varName == null) {
                        continue;
                    }

                    try {
                        Object variable = beanWrapper.unwrap(config.getSharedVariable((String)varName));

                        if (log.isDebugEnabled()) {
                            log.debug("put : " + varName + ", variable : " + variable);
                        }

                        request.setAttribute((String)varName, variable);
                    } catch (TemplateModelException e1) {
                        log.error(e1);
                    }

                }
            }

        });

        return actionInvocation.invoke();
    }

}
